package com.maizhi.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.maizhi.model.Files;
import com.sina.sae.storage.SaeStorage;
import com.sina.sae.util.SaeUserInfo;
 
/**
 * 上传下载模型类
 * 
 * @author Administrator
 * 
 */
public class uploadSpringSinaUtil
{

	Logger logger = Logger.getLogger(uploadSpringSinaUtil.class);
	
	private String path;// 路径
	private String postfix;// 后缀
	private String change;// 变更后的名字
	private String fileName;// 文件名
	private Long fileSize = 0L;// 文件大小
	private Integer docId = 0;
	
	public static ResourceBundle config ;
	
	private String SavePath;
	private String SaveBAKPath;
	//设置上传文件最大值
	private long MAX_SIZE = 300 * 1024 * 1024;
	//默认的文件上传类型限制
    private String allowFileTypes;
    
    private String accessKey;
    private String secretKey;
    private String appName;
    private String seaTempPath;
    private String domain;

    public uploadSpringSinaUtil(){
    	config = ResourceBundle.getBundle("config");
		allowFileTypes= config.getString("allowFileTypes");
		SavePath = config.getString("SavePath");
		SaveBAKPath = config.getString("SaveBAKPath");
		
		accessKey = config.getString("accessKey");
		secretKey = config.getString("secretKey");
		appName   = config.getString("appName");
		seaTempPath=config.getString("seaTempPath");
		domain    = config.getString("domain");
		
		File SavePathFile = new File(SavePath);
		File SaveBAKPathFile = new File(SaveBAKPath);
		if(!SavePathFile.isDirectory()){
			SavePathFile.mkdir();
		}
		
		if(!SaveBAKPathFile.isDirectory()){
			SaveBAKPathFile.mkdir();
		}
		
    }
    
	public Integer getDocId()
	{
		return docId;
	}

	public void setDocId(Integer docId)
	{
		this.docId = docId;
	}

	// 文件大小
	public Long getFileSize()
	{
		return fileSize;
	}

	public void setFileSize(Long fileSize)
	{
		this.fileSize = fileSize;
	}

	/**
	 * 
	 * 路径
	 * 
	 * @return
	 */
	public String getPath()
	{
		return path;
	}

	public void setPath(String path)
	{
		this.path = path;
	}

	/**
	 * 后缀
	 * 
	 * @return
	 */
	public String getPostfix()
	{
		return postfix;
	}

	public void setPostfix(String postfix)
	{
		this.postfix = postfix;
	}

	/**
	 * 变更后的名字
	 * 
	 * @return
	 */
	public String getChange()
	{
		return change;
	}

	/**
	 * 文件名
	 * 
	 * @param change
	 */
	public void setChange(String change)
	{
		this.change = change;
	}

	public String getFileName()
	{
		return fileName;
	}

	public void setFileName(String fileName)
	{
		this.fileName = fileName;
	}
	
	/**
     * 设置允许上传的文件类型，默认是""，无限制
     * 
     * @param allowFileTypes
     */
    public void setAllowFileTypes(String allowFileTypes)
    {
        this.allowFileTypes = allowFileTypes;
    }

    public void addAllowFileTypes(String allowFileTypes)
    {
        this.allowFileTypes += ("," + allowFileTypes);
    }
    
    private boolean isAllowFileType(String fileType)
    {
        if (allowFileTypes.length() > 0 && fileType.trim().length() > 0)
            return allowFileTypes.indexOf(fileType.toLowerCase()) != -1;
        else
            return true;
    }
 

	public List<Files> upload(HttpServletRequest request,HttpServletResponse response)
	{
		String postfix = "";// 后缀
		String change = "";// 变更后的名字
		String fileName = "";// 文件名
		String msg="";
		
		String realPath = SaeUserInfo.getSaeTmpPath() + "/";
		logger.info("realPath :"+realPath);
		logger.info("seaTempPath: "+seaTempPath);
		logger.info("tmpDir : "+System.getProperty("java.io.tmpdir"));
		
		List<Files> list = new ArrayList();
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		// 获得文件：
		MultipartFile file = multipartRequest.getFile("file");
		 
		logger.info("file.getContentType() : "+file.getContentType());
		logger.info("this.isAllowFileType : "+this.isAllowFileType(file.getContentType()));
		
		if(this.isAllowFileType(file.getContentType())){

			logger.info("file : "+file);
			// 获得文件名：
			fileName = file.getOriginalFilename();
			logger.info("fileName : "+fileName);

			if (null != fileName && !"".equals(fileName))
			{
				setFileName(fileName);
				setPath(SavePath);

				// 文件大小
				setFileSize(file.getSize());
				logger.info("file.getSize() : "+file.getSize());

				try
				{
					if (-1 != fileName.indexOf("."))
						postfix = fileName.substring(fileName.lastIndexOf("."));
					//拓展名
					setPostfix(postfix);
					//根据当前时间生成新名称
					change = new SimpleDateFormat("yyyyMMddHHmmssms").format(new Date());
					setChange(change + postfix);

					InputStream stream = file.getInputStream();
//					FileOutputStream fs = new FileOutputStream(realPath+"/"+change + postfix);
//
//					byte[] buffer = new byte[1024 * 1024];
//					int byteread = 0;
//					while ((byteread = stream.read(buffer)) != -1)
//					{
//						fs.write(buffer, 0, byteread);
//						fs.flush();
//					}
					
//					FileOutputStream outputStream = new FileOutputStream("saestor://"+domain+"/"+fileName);
//				    Writer writer = new OutputStreamWriter(outputStream);
//				    writer.close();
					
					
					logger.info("domain : "+domain);
					logger.info("getChange() :"+getChange());
					
					SaeStorage ss = new SaeStorage(accessKey,secretKey,appName);
					ss.write(domain, getChange(),file.getBytes());
					
					logger.info("*******************");
					ss.upload(domain,realPath,fileName);
					
					Files f = new Files();
					f.setId(change);
					f.setFileName(fileName);
					f.setFlagName(change + postfix);
					f.setFilePath(SavePath);
					f.setFileSize(file.getSize());
					f.setFileStatus(1);
					f.setFileSubffix(postfix);
					f.setCreateDate(new Date());
					list.add(f);
					
//					fs.close();
//					stream.close();
				} catch (Exception e1)
				{
					logger.error("upload exception : "+e1.getMessage());
					request.setAttribute("uploadMsg",e1.getMessage());
				}
			}else{
				msg="不属于允许上传文件类型";
			}
		}
		request.setAttribute("uploadMsg",msg);
		return list;
	}

	/**
	 * 文 件下载
	 * @param docId
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	public String dowload(Files files, HttpServletRequest request, HttpServletResponse response) throws IOException
	{
		String msg="";
		response.setContentType("application/vnd.ms-excel");
		String fileName = files.getFlagName(); 
		String nowPath = files.getFilePath()+"/"+files.getFlagName(); 
		File file = new File(nowPath);
		
		if(!file.exists()){
			msg="File not found";
			return msg;
		}
		
		//转码之后下载的文件不会出现中文乱码 获取上传文件的原名
		fileName = new String(files.getFileName().getBytes("GBK"),"ISO8859_1");     
		
		//清空response
		response.reset();
		try
		{
			// 设置response的Header 
			response.addHeader("Content-Disposition", "attachment;filename="+fileName); 
			response.addHeader("Content-Length", "" + file.length());
			// 以流的形式下载文件
			InputStream fis = new BufferedInputStream(new FileInputStream(nowPath));
			logger.info("fis.available() : "+fis.available());
			byte[] buffer = new byte[fis.available()]; //fis.available()
			fis.read(buffer);
			fis.close();
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
		} catch (Exception e)
		{
			msg="下载异常： "+e.getMessage();
		}
	    logger.error(msg);
		request.setAttribute("downMsg", msg);
		return msg;
	}
	
	
	public void dowload(Files files,HttpServletRequest request,HttpServletResponse response,boolean isOnLine) throws Exception
	{
		String msg="";
    	String filePath = files.getFilePath()+files.getFlagName();
		File f = new File(filePath);
		if(!f.exists())
		{
			msg="File not found, fileName:"+files.getFilePath();
			return;
		}
		
		BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
		byte[] buf = new byte[1024];
		int len = 0;
		
		//获取之前的文件名 数据库操作
		String fileName = new String(files.getFileName().getBytes("GBK"),"ISO8859_1");       
		
		response.reset(); //非常重要
		if(isOnLine)//在线打开方式
		{ 
			URL u = new URL("file:///"+filePath);
			response.setContentType("application/zip");
			if (u.openConnection().getContentType().equals("text/plain") ||
				u.openConnection().getContentType().equals("text/xml") ||
				u.openConnection().getContentType().equals("text/html"))
			{
				response.setContentType(u.openConnection().getContentType()+";charset=GB2312");
			}else response.setContentType(u.openConnection().getContentType()+";charset=UTF-8");
			//text/html
			 
			response.setHeader("Content-Disposition", "inline; filename="+fileName);
			//文件名应该编码成UTF-8
		}else
		{ 	//纯下载方式
			response.setContentType("application/x-msdownload"); 
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName); 
		}	
		
		OutputStream out = response.getOutputStream();
		while((len = br.read(buf)) >0)
		out.write(buf,0,len);
		br.close();
		out.close();
		logger.error(msg);
		request.setAttribute("downMsg", msg);
	} 
	
	
	/**
	 * 
	 * 文件大小转换
	 * 
	 * @param size
	 * @return
	 */
	public static String getFormatSize(double size)
	{
		double kiloByte = size / 1024;
		if (kiloByte < 1)
		{
			return size + "Byte(s)";
		}

		double megaByte = kiloByte / 1024;
		if (megaByte < 1)
		{
			BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
			return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
		}

		double gigaByte = megaByte / 1024;
		if (gigaByte < 1)
		{
			BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
			return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
		}

		double teraBytes = gigaByte / 1024;
		if (teraBytes < 1)
		{
			BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
			return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
		}
		BigDecimal result4 = new BigDecimal(teraBytes);
		return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
	}
}